using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;

namespace HslControls.GameSupport
{
	/// <summary>
	/// 俄罗斯方块游戏的引擎
	/// </summary>
	public class TetrisEngine : ClassicGameEngine
	{
		private List<Point[]> list = new List<Point[]>
		{
			new Point[4]
			{
				new Point(0, 0),
				new Point(0, 1),
				new Point(1, 1),
				new Point(1, 0)
			},
			new Point[4]
			{
				new Point(0, 0),
				new Point(0, 1),
				new Point(0, 2),
				new Point(0, 3)
			},
			new Point[4]
			{
				new Point(0, 0),
				new Point(0, 1),
				new Point(1, 1),
				new Point(1, 2)
			},
			new Point[4]
			{
				new Point(0, 2),
				new Point(0, 1),
				new Point(1, 1),
				new Point(1, 0)
			},
			new Point[4]
			{
				new Point(0, 2),
				new Point(1, 2),
				new Point(1, 1),
				new Point(1, 0)
			},
			new Point[4]
			{
				new Point(0, 0),
				new Point(1, 0),
				new Point(1, 1),
				new Point(2, 0)
			},
			new Point[4]
			{
				new Point(0, 0),
				new Point(0, 1),
				new Point(0, 2),
				new Point(1, 2)
			}
		};

		private Random random = new Random();

		/// <summary>
		/// 用户的活动对象
		/// </summary>
		public MoveGameItem MoveTeries
		{
			get;
			set;
		}

		/// <summary>
		/// 游戏的得分
		/// </summary>
		public int PlayerScore
		{
			get;
			set;
		}

		/// <summary>
		/// 只用指定的长宽来实例化游戏对象
		/// </summary>
		/// <param name="pixelX">列数</param>
		/// <param name="pixelY">行数</param>
		public TetrisEngine(int pixelX, int pixelY)
			: base(pixelX, pixelY)
		{
			MoveTeries = new MoveGameItem(new Point[4]
			{
				new Point(0, 0),
				new Point(0, 1),
				new Point(1, 1),
				new Point(1, 2)
			}, new Point(base.PixelCol / 2 - 2, 20), new Size(base.PixelCol, base.PixelRow), OnMoveObjectSuccess);
		}

		/// <summary>
		/// 额外绘制的内容
		/// </summary>
		/// <param name="g">绘制对象</param>
		protected override void DrawCustomer(Graphics g)
		{
			base.DrawCustomer(g);
			DrawGameItem(g, MoveTeries);
		}

		/// <summary>
		/// 清除所有的满行的信息
		/// </summary>
		/// <returns>成功清楚的行数信息</returns>
		private int ClearLines()
		{
			int count = 0;
			for (int i = 0; i < base.PixelRow; i++)
			{
				while (IsRowAllHasItem(i))
				{
					count++;
					LinesMoveDown(i);
				}
			}
			return count;
		}

		/// <summary>
		/// 游戏是否结束
		/// </summary>
		/// <returns></returns>
		private bool IsGameOver()
		{
			for (int i = 0; i < base.PixelCol; i++)
			{
				if (gameArrays[i, base.PixelRow - 1].HasItem)
				{
					return true;
				}
			}
			return false;
		}

		/// <summary>
		/// 获取得分信息
		/// </summary>
		/// <param name="line">一次性消除的行数数据</param>
		/// <returns></returns>
		private int GetScoreFromLinesClear(int line)
		{
			return line switch
			{
				0 => 0, 
				1 => 1, 
				2 => 3, 
				3 => 6, 
				4 => 10, 
				_ => 0, 
			};
		}

		/// <summary>
		/// 判断当前的点位数据是否有碰撞情况
		/// </summary>
		/// <param name="points">等待检测的点位数据</param>
		/// <returns>是否有碰撞的情况</returns>
		private bool OnMoveObjectSuccess(Point[] points)
		{
			for (int i = 0; i < points.Length; i++)
			{
				if (points[i].X >= 0 && points[i].X < base.PixelCol && points[i].Y >= 0 && points[i].Y < base.PixelRow + 4)
				{
					if (points[i].Y < base.PixelRow && gameArrays[points[i].X, points[i].Y].HasItem)
					{
						return false;
					}
					continue;
				}
				return false;
			}
			return true;
		}

		/// <summary>
		/// 点击了向左的按钮
		/// </summary>
		public void MoveLeft()
		{
			MoveTeries.MoveLeft();
			OnBitmapShow(GetRenderBitmap());
		}

		/// <summary>
		/// 点击了向右的按钮
		/// </summary>
		public void MoveRight()
		{
			MoveTeries.MoveRight();
			OnBitmapShow(GetRenderBitmap());
		}

		/// <summary>
		/// 点击了向上的按钮
		/// </summary>
		public void RotationChange()
		{
			MoveTeries.RotationChange();
			OnBitmapShow(GetRenderBitmap());
		}

		/// <summary>
		/// 游戏向下继续运行的时候，需要调用的方法。返回0，不处理，1，游戏继续，2，游戏结束
		/// </summary>
		/// <returns>返回0，不处理，1，游戏继续，2，游戏结束</returns>
		public int MoveDown()
		{
			if (OnMoveObjectSuccess(MoveTeries.GetDownPoints()))
			{
				MoveTeries.MoveDown();
				OnBitmapShow(GetRenderBitmap());
				return 0;
			}
			SetPointFixed(MoveTeries);
			MoveTeries.Location = MoveTeries.LocationDefault;
			int lines = ClearLines();
			if (!IsGameOver())
			{
				PlayerScore += GetScoreFromLinesClear(lines);
				OnBitmapShow(GetRenderBitmap());
				return 1;
			}
			return 2;
		}

		/// <summary>
		/// 获取随机的游戏活动单元的点位信息
		/// </summary>
		/// <returns></returns>
		public Point[] GetNewItemPoints()
		{
			return list[random.Next(list.Count)].ToArray();
		}
	}
}
